package org.apache.tomcat.util.descriptor.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.xml.sax.InputSource;

import com.github.netty.core.util.ResourceManager;

@Deprecated
public class FragmentJarScannerCallback {
	private static final String FRAGMENT_LOCATION = "META-INF/web-fragment.xml";
	private final WebXmlParser webXmlParser;
	private final boolean delegate;
	private final boolean parseRequired;
	private final Map<String, WebXml> fragments = new HashMap<>();
	private boolean ok = true;

	public FragmentJarScannerCallback(WebXmlParser webXmlParser, boolean delegate, boolean parseRequired) {
		this.webXmlParser = webXmlParser;
		this.delegate = delegate;
		this.parseRequired = parseRequired;
	}

	public void scan(ResourceManager resourceManager, String webappPath, boolean isWebapp) throws IOException {

		InputStream is = null;
		WebXml fragment = new WebXml();
		fragment.setWebappJar(isWebapp);
		fragment.setDelegate(delegate);

		try {
			// Only web application JARs are checked for web-fragment.xml
			// files.
			// web-fragment.xml files don't need to be parsed if they are never
			// going to be used.
			if (isWebapp && parseRequired) {
				is =resourceManager.getResourceAsStream(FRAGMENT_LOCATION);
			}

			if (is == null) {
				// If there is no web.xml, normal JAR no impact on
				// distributable
				fragment.setDistributable(true);
			} else {
				String fragmentUrl = resourceManager.getRealPath(FRAGMENT_LOCATION);
				InputSource source = new InputSource(fragmentUrl);
				source.setByteStream(is);
				if (!webXmlParser.parseWebXml(source, fragment, true)) {
					ok = false;
				}
			}
		} finally {
//			addFragment(fragment, jar.getJarFileURL());
		}
	}

	private String extractJarFileName(URL input) {
		String url = input.toString();
		if (url.endsWith("!/")) {
			// Remove it
			url = url.substring(0, url.length() - 2);
		}

		// File name will now be whatever is after the final /
		return url.substring(url.lastIndexOf('/') + 1);
	}

	
	public void scan(File file, String webappPath, boolean isWebapp) throws IOException {

		WebXml fragment = new WebXml();
		fragment.setWebappJar(isWebapp);
		fragment.setDelegate(delegate);

		File fragmentFile = new File(file, FRAGMENT_LOCATION);
		try {
			if (fragmentFile.isFile()) {
				try (InputStream stream = new FileInputStream(fragmentFile)) {
					InputSource source = new InputSource(fragmentFile.toURI().toURL().toString());
					source.setByteStream(stream);
					if (!webXmlParser.parseWebXml(source, fragment, true)) {
						ok = false;
					}
				}
			} else {
				// If there is no web.xml, normal folder no impact on
				// distributable
				fragment.setDistributable(true);
			}
		} finally {
			addFragment(fragment, file.toURI().toURL());
		}
	}

	private void addFragment(WebXml fragment, URL url) {
		fragment.setURL(url);
		if (fragment.getName() == null) {
			fragment.setName(url.toString());
		}
		fragment.setJarName(extractJarFileName(url));
		if (fragments.containsKey(fragment.getName())) {
			// Duplicate. Mark the fragment that has already been found with
			// this name as having a duplicate so Tomcat can handle it
			// correctly when the fragments are being ordered.
			String duplicateName = fragment.getName();
			fragments.get(duplicateName).addDuplicate(url.toString());
			// Rename the current fragment so it doesn't clash
			fragment.setName(url.toString());
		}
		fragments.put(fragment.getName(), fragment);
	}

	
	public void scanWebInfClasses() {
		// NO-OP. Fragments unpacked in WEB-INF classes are not handled,
		// mainly because if there are multiple fragments there is no way to
		// handle multiple web-fragment.xml files.
	}

	public boolean isOk() {
		return ok;
	}

	public Map<String, WebXml> getFragments() {
		return fragments;
	}

}
